package com.lib76.buildCode.service;

import java.io.File;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lib76.buildCode.Constants;
import com.lib76.buildCode.build.common.ConstantsClassBuilder;
import com.lib76.buildCode.build.entry.EntryServiceCodeBuilder;
import com.lib76.buildCode.build.entry.EntrySimpleJspBuilder;
import com.lib76.buildCode.build.jpa.DbModelClassBuilder;
import com.lib76.buildCode.build.jpa.DbModelDaoClassBuilder;
import com.lib76.buildCode.build.maven.MavenProjectBuilder;
import com.lib76.buildCode.build.project.RunJarProjectBuilder;
import com.lib76.buildCode.build.project.WebProjectBuilder;
import com.lib76.buildCode.build.sql.MySqlCreateTableSqlBuilder;
import com.lib76.buildCode.build.utils.UtilsClassBuilder;
import com.lib76.buildCode.build.website.simple.JspManagerPageBuilder;
import com.lib76.buildCode.build.website.simple.JspPageBuilder;
import com.lib76.buildCode.build.website.simple.ManageControllerBuilder;
import com.lib76.buildCode.model.BuildCodeResult;
import com.lib76.buildCode.model.Project;
import com.lib76.jsp.HttpServletUtils;

/**
 * 代码生成服务
 * @author 张浩
 * @version 0.0.2
 */
public class BuilderServer {
	
	private static final Logger logger = LoggerFactory.getLogger(BuilderServer.class);
	
	final static ConcurrentMap<String,ProjectCodeBuildFuture> STORE = new ConcurrentHashMap<String,ProjectCodeBuildFuture>();
	
	private static final ExecutorService pool = Executors.newCachedThreadPool();

	/**
	 * 开始生成代码
	 * @param project
	 * @return
	 */
	public static ProjectCodeBuildFuture startBuild(Project project){
		final  ProjectCodeBuildFuture future = new ProjectCodeBuildFuture(project);
		future.setCurrentRealPath(HttpServletUtils.getRealPath("")); //设置当前项目目录
		pool.execute(new Runnable(){
			public void run() {
				try{
					//创建项目目录
					if(createProjectFile(future)){
						//创建Maven项目构建器并生成Maven项目
						IBuilder builder = new MavenProjectBuilder(); 
						builder.build(future);
						if(future.getSuccess()){
							if(Constants.PROJECT_TYPE_WAR.equals(future.getProject().getProjectType())){
								builder = new WebProjectBuilder();
								builder.build(future);
							}else if(Constants.PROJECT_TYPE_JAR.equals(future.getProject().getProjectType())){
								builder = new RunJarProjectBuilder();
								builder.build(future);
							}else{
								future.put(new BuildCodeResult("","未知的项目类型"));
							}
						}
						if(future.getSuccess() && future.getProject().getDbConfig() != null){
							//生成数据库表实体
							builder = new DbModelClassBuilder();
							builder.build(future);
							if(future.getSuccess()){
								builder = new DbModelDaoClassBuilder();
								builder.build(future);
							}
						}
						//生成Mysql建表语句
						if(future.getSuccess() && future.getProject().getDbConfig() != null){
							builder = new MySqlCreateTableSqlBuilder();
							builder.build(future);
						}
						if(future.getSuccess() && future.getProject().getPageConfig() != null){
							if("simple".equals(future.getProject().getPageConfig().getTemplateType())){
								websiteSimpleBuilder(future);
							}
						}
						if(future.getSuccess() && future.getProject().getPlugs() != null){
							for(int i=0;i<future.getProject().getPlugs().length;i++){
								String name = future.getProject().getPlugs()[i];
								if("security".equals(name)){
									SecurityBuilder(future);
								}
							}
						}
						//生成工具类
						if(future.getSuccess()){
							builder = new UtilsClassBuilder();
							builder.build(future);
						}
						//生成全局常量
						if(future.getSuccess()){
							 builder = new ConstantsClassBuilder();
							 builder.build(future);
						}
						//执行所有延迟代码构建器
						for(IDelayBuilder<?> delayBuilder : future.getDelayBuilders().values()){
							if(future.getSuccess()){
								delayBuilder.build(future);
							}
						}
						//压缩生成的代码
						String path = Constants.PROJECT_PATH+"/" +future.getProject().getProjectCode()+".zip";
						if(ZipUtils.compressDirectory(new File(future.getProjectFileRealPath()), future.getRealPath(Constants.PROJECT_PATH))){
							future.setProjectZipFilePath(path);
						}else{
							future.put(new BuildCodeResult(path,"创建项目代码压缩文件失败"));
						}
					}
				}catch(Exception e){
					logger.error("代码生成时错误",e);
				}
			}
		});
		return future;
	}
	
	
	public static void addFuture(ProjectCodeBuildFuture future){
		STORE.put(future.getProject().getProjectCode(), future);
	}
	
	public static ProjectCodeBuildFuture getFuture(String code){
		return STORE.get(code);
	}
	
	/**
	 * 创建项目文件
	 * @param projectCode
	 * @return
	 */
	public static boolean createProjectFile(ProjectCodeBuildFuture future){
		try{
			File projectFile = new File(future.getRealPath(Constants.PROJECT_PATH+"/"+future.getProject().getProjectCode()));
			if(projectFile.exists()){FileUtils.deleteDirectory(projectFile);}
			if(projectFile.mkdirs()){
				future.setProjectFileRealPath(projectFile.getPath());
				return true;
			}
		}catch(Exception e){
			logger.error("msg=创建项目文件失败`projectCode="+future.getProject().getProjectCode(),e);
		}
		return false;
	}
	
	public static void SecurityBuilder(ProjectCodeBuildFuture future){
		IBuilder builder = new EntryServiceCodeBuilder();
		builder.build(future);
		if(future.getSuccess()){
			builder = new EntrySimpleJspBuilder();
			builder.build(future);
		}
	}
	
	/**
	 * WEB页面生成
	 * @param future
	 */
	public static void websiteSimpleBuilder(ProjectCodeBuildFuture future){
		IBuilder builder = new ManageControllerBuilder();
		builder.build(future);
		if(future.getSuccess()){
			builder = new JspPageBuilder();
			builder.build(future);
		}
		if(future.getSuccess()){
			builder = new JspManagerPageBuilder();
			builder.build(future);
		}
	}
}
